/*
 * commons is a based project implemented
 * Copyright (C) 2024 Jasmine
 */
package com.easy.core.utils;

import java.time.*;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;

/**
 * 时间工具类
 *
 * @author Jasmine
 * @since 1.0.0
 */
public class LocalDateTimeStartUtils {

    /*public static void main(String[] args) {
        System.out.println(LocalDateTime.of(LocalDate.now().with(DayOfWeek.MONDAY), LocalTime.MIN));
        System.out.println("今天开始时间：" + startTimeToday());
        System.out.println("昨天开始时间：" + startTimeByDay(-1));
        System.out.println("明天开始时间：" + startTimeByDay(1));
    
        System.out.println("最近7天开始时间：" + startTimeLast7Days());
        System.out.println("最近30天开始时间：" + startTimeLast30Days());
    
        System.out.println("本周开始时间：" + startTimeWeek());
        System.out.println("本月开始时间：" + startTimeMonth());
        System.out.println("本季度开始时间：" + startTimeQuarter());
        System.out.println("本半年开始时间：" + startTimeHalfYear());
        System.out.println("本年开始时间：" + startTimeYear());
        System.out.println("获取指定月份月第一天：" + startTimeByMonth(LocalDate.of(2021, 11, 30)));
    
        System.out.println("最近一年开始时间：" + startTimeLast1Year());
        System.out.println("上周开始时间：" + startTimeLastWeek());
        System.out.println("上月开始时间：" + startTimeLastMonth());
        System.out.println("上季度开始时间：" + startTimeLastQuarter());
        System.out.println("上半年开始时间：" + startTimeLastHalfYear());
        System.out.println("上一年开始时间：" + startTimeLastYear());
        System.out.println("下周开始时间：" + startTimeNextWeek());
        System.out.println("下月开始时间：" + startTimeNextMonth());
        System.out.println("下季度开始时间：" + startTimeNextQuarter());
        System.out.println("下半年开始时间：" + startTimeNextHalfYear());
        System.out.println("下一年开始时间：" + startTimeNextYear());
    }*/

    /**
     * 今天开始时间
     */
    public static LocalDateTime startTimeToday() {
        return LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
    }

    /**
     * 当前时间开始 +- 天数 eg:昨天开始时间=startTimeByDay(-1)
     */
    public static LocalDateTime startTimeByDay(long amountToSubtract) {
        return LocalDateTime.of(LocalDate.now().plus(amountToSubtract, ChronoUnit.DAYS), LocalTime.MIN);
    }

    /**
     * 最近7天开始时间
     */
    public static LocalDateTime startTimeLast7Days() {
        return LocalDateTime.of(LocalDate.now().plus(-6L, ChronoUnit.DAYS), LocalTime.MIN);
    }

    /**
     * 最近30天开始时间
     */
    public static LocalDateTime startTimeLast30Days() {
        return LocalDateTime.of(LocalDate.now().plus(-29L, ChronoUnit.DAYS), LocalTime.MIN);
    }

    /**
     * 本周开始时间
     */
    public static LocalDateTime startTimeWeek() {
        return LocalDateTime.of(LocalDate.now().with(DayOfWeek.MONDAY), LocalTime.MIN);
    }

    /**
     * 本月开始时间
     */
    public static LocalDateTime startTimeMonth() {
        return LocalDateTime.of(LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()), LocalTime.MIN);
    }

    /**
     * 本季度开始时间
     */
    public static LocalDateTime startTimeQuarter() {
        LocalDate now = LocalDate.now();
        Month month = now.getMonth().firstMonthOfQuarter();
        return LocalDateTime.of(LocalDate.of(now.getYear(), month, 1), LocalTime.MIN);
    }

    /**
     * 本半年开始时间
     */
    public static LocalDateTime startTimeHalfYear() {
        LocalDate now = LocalDate.now();
        Month month = (now.getMonthValue() > 6) ? Month.JULY : Month.JANUARY;
        return LocalDateTime.of(LocalDate.of(now.getYear(), month, 1), LocalTime.MIN);
    }

    /**
     * 本年开始时间
     */
    public static LocalDateTime startTimeYear() {
        return LocalDateTime.of(LocalDate.now().with(TemporalAdjusters.firstDayOfYear()), LocalTime.MIN);
    }

    /**
     * 获取指定月份月第一天
     */
    public static LocalDateTime startTimeByMonth(LocalDate localDate) {
        return LocalDateTime.of(localDate.with(TemporalAdjusters.firstDayOfMonth()), LocalTime.MIN);
    }

    /**
     * 最近一年开始时间
     */
    public static LocalDateTime startTimeLast1Year() {
        return LocalDateTime.of(LocalDate.now().minus(1L, ChronoUnit.YEARS).plus(1L, ChronoUnit.DAYS), LocalTime.MIN);
    }

    /**
     * 上周开始时间
     */
    public static LocalDateTime startTimeLastWeek() {
        LocalDate lastWeek = LocalDate.now().minus(1L, ChronoUnit.WEEKS);
        return LocalDateTime.of(lastWeek.minusDays(lastWeek.getDayOfWeek().getValue() - 1), LocalTime.MIN);
    }

    /**
     * 上月开始时间
     */
    public static LocalDateTime startTimeLastMonth() {
        return LocalDateTime.of(LocalDate.now().minus(1L, ChronoUnit.MONTHS).with(TemporalAdjusters.firstDayOfMonth()),
            LocalTime.MIN);
    }

    /**
     * 上季度开始时间
     */
    public static LocalDateTime startTimeLastQuarter() {
        LocalDate now = LocalDate.now();
        Month firstMonthOfQuarter = Month.of(now.getMonth().firstMonthOfQuarter().getValue());
        Month firstMonthOfLastQuarter = firstMonthOfQuarter.minus(3L);
        int yearOfLastQuarter = firstMonthOfQuarter.getValue() < 4 ? now.getYear() - 1 : now.getYear();
        return LocalDateTime.of(LocalDate.of(yearOfLastQuarter, firstMonthOfLastQuarter, 1), LocalTime.MIN);
    }

    /**
     * 上半年开始时间
     */
    public static LocalDateTime startTimeLastHalfYear() {
        LocalDate now = LocalDate.now();
        int lastHalfYear = (now.getMonthValue() > 6) ? now.getYear() : now.getYear() - 1;
        Month firstMonthOfLastHalfYear = (now.getMonthValue() > 6) ? Month.JANUARY : Month.JULY;
        return LocalDateTime.of(LocalDate.of(lastHalfYear, firstMonthOfLastHalfYear, 1), LocalTime.MIN);
    }

    /**
     * 上一年开始时间
     */
    public static LocalDateTime startTimeLastYear() {
        return LocalDateTime.of(LocalDate.now().minus(1L, ChronoUnit.YEARS).with(TemporalAdjusters.firstDayOfYear()),
            LocalTime.MIN);
    }

    /**
     * 下周开始时间
     */
    public static LocalDateTime startTimeNextWeek() {
        LocalDate nextWeek = LocalDate.now().plus(1L, ChronoUnit.WEEKS);
        return LocalDateTime.of(nextWeek.minusDays(nextWeek.getDayOfWeek().getValue() - 1), LocalTime.MIN);
    }

    /**
     * 下月开始时间
     */
    public static LocalDateTime startTimeNextMonth() {
        return LocalDateTime.of(LocalDate.now().plus(1L, ChronoUnit.MONTHS).with(TemporalAdjusters.firstDayOfMonth()),
            LocalTime.MIN);
    }

    /**
     * 下季度开始时间
     */
    public static LocalDateTime startTimeNextQuarter() {
        LocalDate now = LocalDate.now();
        Month firstMonthOfQuarter = Month.of(now.getMonth().firstMonthOfQuarter().getValue());
        Month firstMonthOfNextQuarter = firstMonthOfQuarter.plus(3L);
        int yearOfNextQuarter = firstMonthOfQuarter.getValue() > 9 ? now.getYear() + 1 : now.getYear();
        return LocalDateTime.of(LocalDate.of(yearOfNextQuarter, firstMonthOfNextQuarter, 1), LocalTime.MIN);
    }

    /**
     * 上半年开始时间
     */
    public static LocalDateTime startTimeNextHalfYear() {
        LocalDate now = LocalDate.now();
        int nextHalfYear = (now.getMonthValue() > 6) ? now.getYear() + 1 : now.getYear();
        Month firstMonthOfNextHalfYear = (now.getMonthValue() > 6) ? Month.JANUARY : Month.JULY;
        return LocalDateTime.of(LocalDate.of(nextHalfYear, firstMonthOfNextHalfYear, 1), LocalTime.MIN);
    }

    /**
     * 下一年开始时间
     */
    public static LocalDateTime startTimeNextYear() {
        return LocalDateTime.of(LocalDate.now().plus(1L, ChronoUnit.YEARS).with(TemporalAdjusters.firstDayOfYear()),
            LocalTime.MIN);
    }
}
